package com.whx.authorization.web.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.whx.authorization.constant.AuthorizationConstant;
import com.whx.authorization.web.domain.LogoutInfo;
import com.whx.authorization.response.*;
import com.whx.authorization.util.UrlParamUtil;
import com.whx.authorization.web.constants.SessionConstants;
import com.whx.authorization.web.service.AuthorizationService;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * 类名：AuthorizationAction
 * 类路径： com.whx.authorization.web.action.AuthorizationAction
 * 创建者： whx
 * 创建时间： 10/8/18 9:10 AM
 * 项目： authorization_center
 * 描述：
 */
@Controller("authorization/")
public class AuthorizationAction {


    /**
     * 检查服务是否存活
     * @return
     */
    @RequestMapping("checkAlive")
    @ResponseBody
    public JSONObject checkAlive() {
        CheckAliveResponse alive = new CheckAliveResponse();
        alive.setSuccess(true);
        return JSON.parseObject(JSON.toJSONString(alive));
    }


    /**
     * 认证成功后子系统退出信息注册
     * @param logoutUrl 子系统退出地址
     * @param logoutParam 退出参数
     * @param cookieString 退出用cookie值
     * @param httpMethod 退出请求方式 get/post 默认get
     * @param session
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping(value = "registerSubSystem", method = RequestMethod.POST, headers = {"AuthorizationType0=registerSubSystem"})
    @ResponseBody
    public JSONObject registerSubSystem(String logoutUrl, String logoutParam, String cookieString, String httpMethod,HttpSession session) throws IOException {
        RegisterSubSystemResponse resp = new RegisterSubSystemResponse();
        if (!StringUtils.isEmpty(logoutUrl) && !StringUtils.isEmpty(logoutParam)) {
            List<LogoutInfo> logoutInfoQueue = (List<LogoutInfo>) session.getAttribute(SessionConstants.LOGOUT_QUEUE);
            if (logoutInfoQueue == null) {
                logoutInfoQueue = new ArrayList<LogoutInfo>();
            }
            String realLogoutUrl = UrlParamUtil.decodeUrlParam(logoutUrl);
            String realLogoutParam = UrlParamUtil.decodeUrlParam(logoutParam);
            LogoutInfo logoutInfo = new LogoutInfo();
            logoutInfo.setLogoutUrl(realLogoutUrl);
            logoutInfo.setLogoutParams(realLogoutParam);
            logoutInfo.setCookieString(cookieString);
            logoutInfo.setHttpMethod(httpMethod);
            logoutInfoQueue.add(logoutInfo);
            session.setAttribute(SessionConstants.LOGOUT_QUEUE, logoutInfoQueue);
            resp.setSuccess(true);
        }
        return JSON.parseObject(JSON.toJSONString(resp));
    }



    /**
     * 内部登录，服务端调起，向认证中心注册用户信息，只接受带特殊header的post请求
     * @param userId
     * @param session
     * @return
     */
    @RequestMapping(value = "internalLogin", method = RequestMethod.POST, headers = {"AuthorizationType0=internalLogin"})
    @ResponseBody
    public JSONObject internalLogin(String userId, HttpSession session) {
        LoginResponse resp = new LoginResponse();
        if (!StringUtils.isEmpty(userId)) {
            String oldUserId = (String) session.getAttribute(SessionConstants.USER_IDENTIFY);
            if (oldUserId != null) {
                if (!Objects.equals(oldUserId, userId)) {
                    List<LogoutInfo> logoutInfos = ((List<LogoutInfo>) session.getAttribute(SessionConstants.LOGOUT_QUEUE));
                    AuthorizationService.subSystemLogout(logoutInfos);
                }
            }
            session.setAttribute(SessionConstants.USER_IDENTIFY, userId);
            resp.setSuccess(true);
        }
        return JSON.parseObject(JSON.toJSONString(resp));
    }

    /**
     * 用户授权
     * @param subAuthorizedUrl 获取授权成功跳转子系统授权获取用户信息地址
     * @param loginUrl 获取授权失败跳转登录地址
     * @param requestState 原本请求需要带的经过utf-8的UrlEncode的QueryString参数，原样返回
     * @param session
     * @return 认证中心已经登录，认证成功，跳转到子系统认证用户信息地址subAuthorizedUrl，认证中心未登录，跳转到子系统登录地址，
     * 子系统使用认证中心返回的参数authorToken0(AuthorizationConstant.AUTHORIZATION_CENTER_SESSION_TRANSLATE_NAME)传递给认证中心进行客户端授权中心的session识别
     * @throws IOException
     */
    @RequestMapping("authorization")
    public String authorization(String subAuthorizedUrl, String loginUrl, String requestState, HttpSession session) throws IOException {
        Long userIdentify = (Long) session.getAttribute(SessionConstants.USER_IDENTIFY);
        String redirectUrl = null;
        if (userIdentify == null) {
            redirectUrl = loginUrl;
        } else {
            redirectUrl = subAuthorizedUrl;
        }
        Map<String, String> paramsMap = new HashMap<String, String>();
        paramsMap.put("requestState", requestState);
        paramsMap.put(AuthorizationConstant.AUTHORIZATION_CENTER_SESSION_TRANSLATE_NAME, UrlParamUtil.encodeUrlParam(session.getId()));
        redirectUrl = UrlParamUtil.buildRequestUrl(redirectUrl, UrlParamUtil.buildQuery(paramsMap));
        return "redirect:" + redirectUrl;
    }

    /**
     * 向认证中心注册过的子系统统一退出
     * @param session
     * @return
     */
    @RequestMapping(value = "internalLogout", method = RequestMethod.POST, headers = {"AuthorizationType0=internalLogout"})
    @ResponseBody
    public JSONObject internalLogout(HttpSession session) {
        List<LogoutInfo> logoutInfos = ((List<LogoutInfo>) session.getAttribute(SessionConstants.LOGOUT_QUEUE));
        AuthorizationService.subSystemLogout(logoutInfos);
        session.invalidate();
        LogoutResponse result = new LogoutResponse();
        result.setSuccess(true);
        return JSON.parseObject(JSON.toJSONString(result));
    }


    @RequestMapping(value = "internalUserInfo", method = RequestMethod.POST, headers = {"AuthorizationType0=internalUserInfo"})
    @ResponseBody
    public JSONObject internalUserInfo(HttpSession session) {
        String userId = ((String) session.getAttribute(SessionConstants.USER_IDENTIFY));
        UserInfoResponse userInfo = new UserInfoResponse();
        if (!StringUtils.isEmpty(userId)) {
            userInfo.setSuccess(true);
            userInfo.setUserId(userId);
        }
        return JSON.parseObject(JSON.toJSONString(userInfo));
    }


}
